// copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
// see COPYRIGHT for reuse legalities
//

#import "RIBBasis.h"
#import "WW3DShape.h"

@implementation RIBBasis

+ initialize { return [RIBBasis setVersion:1], self; }

- init
{
  [super init] ;

  N3D_CopyMatrix(RiBezierBasis, uBasis); 
  uBasisToken = RI_BEZIER;
  uStep = 3; 
  N3D_CopyMatrix(RiBezierBasis, vBasis); 
  vBasisToken = RI_BEZIER;
  vStep = 3; 

  return self;
}

- setUBasis:(RtBasis)newUBasis
     uBasisToken:(RtToken)newUBasisToken
     uStep:(RtInt)newUStep
     vBasis:(RtBasis)newVBasis
     vBasisToken:(RtToken)newVBasisToken
     vStep:(RtInt)newVStep
{
  N3D_CopyMatrix(newUBasis, uBasis); 
  uBasisToken = newUBasisToken;
  uStep = newUStep; 
  N3D_CopyMatrix(newVBasis, vBasis); 
  vBasisToken = newVBasisToken;
  vStep = newVStep; 

  [myShape updateBases];

  return self;
}

- (RtBasis *)uBasis  {  return &uBasis; }
- (RtToken)uBasisToken  {  return uBasisToken; }
- (RtInt)uStep  {  return uStep; }
- (RtBasis *)vBasis  {  return &vBasis; }
- (RtToken)vBasisToken  {  return vBasisToken; }
- (RtInt)vStep  {  return vStep; }

- renderSelf:(WW3DCamera *)camera  startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
{
  RiBasis(uBasis, uStep, vBasis, vStep);
  return self;
}

- (unsigned long int)maxSampleBandwidth {  return ([super maxSampleBandwidth] + (unsigned long int)(16 * 2 * sizeof(RtFloat))); }


- writeEve:(NXStream *)stream atTabLevel:(int)tab
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   // probably should see if we can write out the token, if it's there...
   NXPrintf(stream, "Basis {"); 
   NXPrintf(stream, "%f %f %f %f ",  uBasis[0][0], uBasis[0][1], uBasis[0][2], uBasis[0][3]);
   NXPrintf(stream, "%f %f %f %f ",  uBasis[1][0], uBasis[1][1], uBasis[1][2], uBasis[1][3]);
   NXPrintf(stream, "%f %f %f %f ",  uBasis[2][0], uBasis[2][1], uBasis[2][2], uBasis[2][3]);
   NXPrintf(stream, "%f %f %f %f} ", uBasis[3][0], uBasis[3][1], uBasis[3][2], uBasis[3][3]);
   NXPrintf(stream, "%d ", uStep);
   NXPrintf(stream, "{%f %f %f %f ",  vBasis[0][0], vBasis[0][1], vBasis[0][2], vBasis[0][3]);
   NXPrintf(stream, "%f %f %f %f ",  vBasis[1][0], vBasis[1][1], vBasis[1][2], vBasis[1][3]);
   NXPrintf(stream, "%f %f %f %f ",  vBasis[2][0], vBasis[2][1], vBasis[2][2], vBasis[2][3]);
   NXPrintf(stream, "%f %f %f %f} ", vBasis[3][0], vBasis[3][1], vBasis[3][2], vBasis[3][3]);
   NXPrintf(stream, "%d ", vStep);
   NXPrintf(stream, "; ");

   return self;
}

- read:(NXTypedStream*)stream 
{
    int version;
    [super read:stream];

    version = NXTypedStreamClassVersion(stream,"RIBBasis");
    if (version == 0) NXReadTypes(stream,"i",&version), version=1;
    if (version == 1)
    {  NXReadArray(stream, "f", 4, uBasis[0]);
       NXReadArray(stream, "f", 4, uBasis[1]);
       NXReadArray(stream, "f", 4, uBasis[2]);
       NXReadArray(stream, "f", 4, uBasis[3]);
       NXReadArray(stream, "f", 4, vBasis[0]);
       NXReadArray(stream, "f", 4, vBasis[1]);
       NXReadArray(stream, "f", 4, vBasis[2]);
       NXReadArray(stream, "f", 4, vBasis[3]);
       NXReadTypes(stream, "ii", &uStep, &vStep);
       NXReadTypes(stream, "**", &uBasisToken, &vBasisToken);
    } 
    else 
    {
    }
    return self;
}

- write:(NXTypedStream*)stream 
{
    [super write:stream];

    NXWriteArray(stream, "f", 4, uBasis[0]);
    NXWriteArray(stream, "f", 4, uBasis[1]);
    NXWriteArray(stream, "f", 4, uBasis[2]);
    NXWriteArray(stream, "f", 4, uBasis[3]);
    NXWriteArray(stream, "f", 4, vBasis[0]);
    NXWriteArray(stream, "f", 4, vBasis[1]);
    NXWriteArray(stream, "f", 4, vBasis[2]);
    NXWriteArray(stream, "f", 4, vBasis[3]);
    NXWriteTypes(stream, "ii", &uStep, &vStep);
    NXWriteTypes(stream, "**", &uBasisToken, &vBasisToken);

    return self;
}

@end
